#include  "ws2812.h"
#include "sys.h"

#define 	RGB_LED 	GPIO_Pin_13
#define		RGB_LED_HIGH		(GPIO_SetBits(GPIOB,RGB_LED))
#define 	RGB_LED_LOW		(GPIO_ResetBits(GPIOB,RGB_LED))

u8 MAX_LIT	=	8;

u8 light_set[3] = {0};
u8 down_flag = 0;
struct LIGHT_SET LIGHT_SET1 = {0x0,0x0,0x01};


void RGB_LED_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
 	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;			    	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
	GPIO_Init(GPIOB, &GPIO_InitStructure);					
	GPIO_ResetBits(GPIOB,GPIO_Pin_13);			

	//DelayMs(5);
}

/********************************************************/
//
/********************************************************/
void RGB_LED_Write0(void)
{
	RGB_LED_HIGH;
	__nop();__nop();__nop();__nop();__nop();__nop();
	RGB_LED_LOW;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();
}

/********************************************************/
//
/********************************************************/

void RGB_LED_Write1(void)
{
	RGB_LED_HIGH;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();
	RGB_LED_LOW;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();
}

void RGB_LED_Reset(void)
{
	RGB_LED_LOW;
	DelayUs(80);
}

void RGB_LED_Write_Byte(uint8_t byte)
{
	uint8_t i;

	for(i=0;i<8;i++)
		{
			if(byte&0x80)
				{
					RGB_LED_Write1();
			}
			else
				{
					RGB_LED_Write0();
			}
		byte <<= 1;
	}
}

void RGB_LED_Write_24Bits(uint8_t green,uint8_t red,uint8_t blue)
{
	RGB_LED_Write_Byte(green);
	RGB_LED_Write_Byte(red);
	RGB_LED_Write_Byte(blue);
}

//亮灯颜色设定，其他颜色以此类推
void RGB_LED_Red(void)
{
	 uint8_t i;
	//4个LED全彩灯
	for(i=0;i<4;i++)
		{
			RGB_LED_Write_24Bits(0, 0xff, 0);
	}
}

void RGB_LED_Green(void)
{
	uint8_t i;

	for(i=0;i<4;i++)
		{
			RGB_LED_Write_24Bits(0xff, 0, 0);
	}
}

void RGB_LED_Blue(void)
{
	uint8_t i;

	for(i=0;i<4;i++)
		{
			RGB_LED_Write_24Bits(0, 0, 0xff);
	}
}

// ###################################################################
// ##########################  MY FCNs  ##############################
void MY_2812_FOUR(struct LIGHT_SET light_set){
	for(int i=0;i<4;i++){
					RGB_LED_Write_24Bits(light_set.green  ,light_set.red  ,light_set.blue);
					//DelayUs(1);
				}
	
}

// ###################################################################
struct LIGHT_SET my_2812_breath(struct LIGHT_SET light_set){
		if(!down_flag){
				light_set.green	+=1;
				light_set.red		+=1;
				light_set.blue	+=1;
			}
			else{
				light_set.green	-=1;
				light_set.red		-=1;
				light_set.blue	-=1;
			}
			
			if(light_set.blue> MAX_LIT||
					light_set.red> MAX_LIT||
					light_set.green> MAX_LIT
			){
				light_set.blue 	= MAX_LIT;
				light_set.red		= MAX_LIT;
				light_set.green	= MAX_LIT;
				down_flag = 1;
			}
			else if(light_set.blue == MAX_LIT||
					light_set.red == MAX_LIT||
					light_set.green == MAX_LIT
			){
				down_flag = 1;
			}
			else if(light_set.blue<=0||
					light_set.red<=0 ||
					light_set.green<=0
			)
				down_flag = 0;
	return	light_set;
}


// ###################################################################
struct LIGHT_SET	my_2812_set(char col,	uint8_t val, struct LIGHT_SET light_set){
	
	light_set = light_set;
	switch(col){
		case RED:		light_set.red		=	val;break;
		case GREEN:	light_set.green	=	val;break;
		case BLUE:	light_set.blue	=	val;break;
		case MAX:		MAX_LIT	= val;				break;
	}
	return light_set;
	
}


// ###################################################################
static char last_val = 0;
u8 u8_check_cross(int	val){
	
	if( (val-last_val)>20 )		val = 0;
	if( (val-last_val)<-100 )	val =	255;

	last_val = val;
	return val;
}	

// ###################################################################
u8	set_light_process(u8 col,u8 val,u8 max){
	last_val =col; 
	col += val; 
	col = u8_check_cross(col);	
	if(col>max)	col = max;
	return col;
}


// ###################################################################
struct LIGHT_SET	my_2812_set_dif(char col,	u8 val, struct LIGHT_SET light_set){
	
	light_set = light_set;
	
	
	switch(col){
		case RED:		light_set.red = set_light_process(light_set.red,val,MAX_LIT); 			break;
		case GREEN:	light_set.green = set_light_process(light_set.green,val,MAX_LIT); 	break;
		case BLUE:	light_set.blue = set_light_process(light_set.blue,val,MAX_LIT);  	break;
		case MAX:		MAX_LIT	=	set_light_process(MAX_LIT,val,255);  	break;
	}
	return light_set;
	
}
	





